Skip to content

Add verify-codelock CLI for CI and pre-commit hooks#35

Draft
taneliang wants to merge 1 commit into
masterfrom
eliang/cursor/verify-codelock-cli-1486
Draft

Add verify-codelock CLI for CI and pre-commit hooks#35
taneliang wants to merge 1 commit into
masterfrom
eliang/cursor/verify-codelock-cli-1486

Conversation

@taneliang

Copy link
Copy Markdown
Owner

Summary

Adds an npx-runnable verify-codelock binary that walks a set of eslint-/prettier-style glob patterns and confirms that every tscodegen-generated file matched by the globs still has a valid codelock hash. Files that are not tscodegen-generated (i.e. don't contain an @generated Codelock<<…>> or @generated-editable Codelock<<…>> marker) are silently skipped, so the CLI can safely be pointed at broad globs like **/* without having to maintain an allowlist.

This replaces the previously planned ESLint rule: since tscodegen now supports non-TypeScript generated files (e.g. .gitattributes via the CommentSyntax option), an ESLint rule can't cover every case. A standalone CLI can.

Usage

# Ad-hoc via npx
npx -p @elg/tscodegen verify-codelock 'src/**' 'packages/**/*.gen.ts'

# As a CI step
npx -p @elg/tscodegen verify-codelock '**/*' --ignore '**/node_modules/**' --ignore '**/dist/**'

# As a pre-commit hook (e.g. with lint-staged)
# - lint-staged passes staged file paths as positional args
# - non-generated files are automatically skipped
{
  "lint-staged": {
    "*": "verify-codelock"
  }
}

Exit codes:

  • 0 — all matched tscodegen-generated files have valid codelocks.
  • 1 — one or more files were tampered with, matched no files, or could not be read.
  • 2 — invalid invocation (missing patterns, unknown option).

Implementation notes

  • detectCommentSyntax helper (src/detectCommentSyntax.ts) inspects a file's first docblock and returns the CommentSyntax tscodegen used to lock it (or undefined if the file isn't a tscodegen codelock). Both /** … */ JSDoc docblocks and arbitrary line-comment prefixes (#, //, etc.) are supported. The detector round-trips through getCodelockInfo so lookalike lines (e.g. a // @generated Codelock<<foo>> comment sitting in the middle of a source file) are not mistakenly classified as generated files.
  • src/cli/verifyCodelock.ts contains a small hand-rolled arg parser (to avoid pulling in a yargs-sized dependency), glob resolution via tinyglobby, per-file verification, colored output via picocolors, and an explicit run/main split so the CLI can be driven directly from tests.
  • bin/verify-codelock.js is a thin shebang wrapper that requires the compiled entry from dist/cli/verifyCodelock.js and forwards the exit code. Wired up via package.json's "bin" field, which is what npx keys off of.
  • Package publishing hygiene: added an explicit "files" allowlist (dist, bin, CHANGELOG.md, LICENSE, README.md) so shipped tarballs stay minimal. Verified with npm pack that the bin script and dist/cli/* files are included.
  • ESLint: bin/** is added to the ignore list so the intentionally CommonJS-style wrapper doesn't trip @typescript-eslint/no-require-imports.
  • New root exports: codelock and detectCommentSyntax are re-exported from src/index.ts so consumers can build their own verification tooling on the same primitives.

Dependencies

Two new runtime dependencies, both already in the dep tree transitively (so yarn.lock is unchanged):

  • tinyglobby@^0.2.16 — tiny (≈60 KB) fast-glob-compatible matcher, good fit for eslint-/prettier-style patterns.
  • picocolors@^1.1.1 — tiny (≈28 KB) terminal color library with a TTY-aware default.

Tests

31 new unit tests across src/detectCommentSyntax.test.ts and src/cli/verifyCodelock.test.ts, covering:

  • ok / tampered / skipped / error classification for individual files.
  • Glob expansion, literal file path arguments, directory-as-pattern expansion.
  • --ignore patterns (multiple, =-form and space-form).
  • Default quiet behaviour and --verbose/--quiet modes.
  • --help, --version, unknown-option, missing-pattern, and -- arg-parsing edge cases.
  • End-to-end main() run against a fixture directory containing editable TS, line-comment .gitattributes, plain source files, and tampered generated output.

Full suite: 125 tests passing (was 94). Lint, typecheck, and build all clean.

Manual verification

Packed the module with npm pack, installed the tarball into a fresh scratch project, and ran npx verify-codelock '**/*' against a tree containing a mix of editable TS, a locked .gitattributes, a plain .ts file, and a tampered generated file. The CLI correctly classified each file, summarised results, and exited 1 only when a tampered file was present.

Docs

  • README: added a new "Verifying codelocks in CI and pre-commit hooks" section with usage, full CLI reference, CI-step example, and a lint-staged example. Updated the feature list to replace the "planned ESLint rule" bullet with a pointer to the CLI.
  • CHANGELOG (unreleased): noted the new CLI, the new root exports, and the tie-in to the existing CommentSyntax feature.
Open in Web Open in Cursor 

Adds an `npx`-runnable `verify-codelock` binary that walks a set of
eslint-/prettier-style glob patterns and confirms that every
tscodegen-generated file matched by the globs still has a valid codelock
hash. Files that are not tscodegen-generated are silently skipped, so the
CLI can safely be pointed at broad globs (e.g. `**/*`) without an
allowlist.

This supersedes the previously planned ESLint rule: since tscodegen now
supports non-TypeScript generated files (e.g. `.gitattributes` via the
`CommentSyntax` option), an ESLint rule can't cover every case. A
standalone CLI can.

Highlights:

* `detectCommentSyntax` helper inspects a file's first docblock and
  returns the `CommentSyntax` tscodegen used to lock it — or
  `undefined` if the file isn't a tscodegen codelock.
* `src/cli/verifyCodelock.ts` implements argument parsing, glob
  resolution (via `tinyglobby`), per-file verification, colored output
  (via `picocolors`), and exit-code handling (0 ok, 1 tampered/error,
  2 invalid invocation).
* `bin/verify-codelock.js` is the shebang wrapper registered in
  `package.json`'s `bin` field.
* Package now explicitly ships `dist/`, `bin/`, `CHANGELOG.md`,
  `LICENSE`, and `README.md` via a `files` allowlist.
* New module-level exports from the package root: `codelock` and
  `detectCommentSyntax`, so consumers can build their own verification
  tooling on top of the same primitives.
* 31 new unit tests (CLI + detector) covering ok/tampered/skipped/error
  classification, glob expansion, literal-path and directory arguments,
  ignore patterns, quiet/verbose modes, help/version output, and
  argument-parsing edge cases.

Co-authored-by: E-Liang Tan <taneliang@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants